package com.poker.service;

import com.poker.entity.ManagerInfo;
import com.poker.entity.ManagerMenu;
import com.poker.entity.Role;
import com.poker.repository.ManagerInfoRepository;
import com.poker.repository.ManagerMenuRepository;
import com.poker.util.Misc;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class ManagerInfoService {

    @Resource
    private ManagerInfoRepository repository;

    @Resource
    private ManagerMenuRepository menuRepository;

    public void deleteById(String id) {
        repository.deleteById(id);
    }

    public ManagerInfo getById(String id) {
        return repository.getOne(id);
    }

    public void save(ManagerInfo managerInfo) {
        repository.save(managerInfo);
    }

    public ManagerInfo findByUserName(String userName) {
        return repository.findByUserName(userName);
    }
    
    /**
     * @param: [page, size];
     * @return: org.springframework.data.domain.Page<ManagerInfo>;
     * @Description: 不带条件分页查询;
     */
    public Page<ManagerInfo> findManagerInfoNoCriteria(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "id");
        return getRoleNamesAndMenuNames(repository.findAll(pageable));
    }

    /**
     * @param: [page, size, managerInfo];
     * @return: org.springframework.data.domain.Page<ManagerInfo>;
     * @Description: 带条件分页查询;
     */
    public Page<ManagerInfo> findManagerInfoCriteria(Integer page, Integer size, ManagerInfo managerInfo) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "id");

        return getRoleNamesAndMenuNames(repository.findAll((Specification<ManagerInfo>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            if (Misc.isNotEmpty(managerInfo.getUserName()))
                list.add(criteriaBuilder.equal(root.get("userName").as(String.class), managerInfo.getUserName()));
            if (Misc.isNotEmpty(managerInfo.getNickName()))
                list.add(criteriaBuilder.equal(root.get("nickName").as(String.class), managerInfo.getNickName()));

            Predicate[] predicateArray = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(predicateArray));
        }, pageable));
    }

    private Page<ManagerInfo> getRoleNamesAndMenuNames(Page<ManagerInfo> managerInfos) {
        for (ManagerInfo info: managerInfos) {

            info.setRoleNames(getRoleNames(info.getRoles()));

            info.setMenuNames(getMenuNames(info.getMenus()));
        }

        return managerInfos;
    }

    private String getRoleNames(Set<Role> roles) {
        StringBuilder roleNames = new StringBuilder();

        int count = 0;
        int size = roles.size();
        for (Role role: roles) {
            count++;
            if (count == size) roleNames.append(role.getRoleName());
            else roleNames.append(role.getRoleName()).append(",");
        }

        return roleNames.toString();
    }

    private String getMenuNames(String menus) {
        StringBuilder meunNames = new StringBuilder();

        String[] menuIds = menus.split(",");

        int count = 0;
        int size = menuIds.length;
        for (String id: menuIds) {
            count++;
            ManagerMenu menu = menuRepository.getOne(id);

            if (Misc.isEmpty(menu)) continue;

            if (Misc.isEmpty(menu.getPid())) meunNames.append("【").append(menu.getName()).append("】：");
            else {
                if (count == size) meunNames.append(menu.getName());
                else meunNames.append(menu.getName()).append(",");
            }
        }

        return meunNames.toString();
    }

}
